﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Threading;
using System.Windows;
using PairingMatrix.Common.Enum;
using System.Linq;
using PairingMatrix.Services;
using PairingMatrix.ViewModel;

namespace PairingMatrix.Model
{
    public class CardWallModel : BusinessModelBase
    {
        private readonly PairingMatrixServiceClient _dataService;
        public ObservableCollection<ProjectCardModel> ProjectCards { get; set; }
        public ObservableCollection<TeamMemberModel> TeamMembers { get; set; }
        public ObservableCollection<ProjectCardModel> MingleCards { get; set; }
        

        public CardWallModel(PairingMatrixServiceClient dataService)
        {
            _dataService = dataService;

            _dataService.GetSettingsCompleted += _dataService_GetSettingsCompleted;
            _dataService.GetProjectCardsCompleted += dataService_GetProjectCardsCompleted;
            _dataService.AddProjectCardCompleted += dataService_AddProjectCardCompleted;
            _dataService.GetProjectCardFromMingleCompleted += _dataService_GetProjectCardFromMingleCompleted;
            _dataService.GetProjectCardsFromMingleCompleted += _dataService_GetProjectCardsFromMingleCompleted;

            _dataService.GetTeamMembersCompleted += dataService_GetTeamMembersCompleted;
            _dataService.AddTeamMemberCompleted += _dataService_AddTeamMemberCompleted;

            _dataService.AddCardWallInstanceOnCompleted += dataService_AddCardWallInstanceOnCompleted;
            _dataService.AttachTeamMemberToProjectCardCompleted += _dataService_AttachTeamMemberToProjectCardCompleted;
            _dataService.DetachTeamMemberFromAllProjectCardsCompleted += _dataService_DetachTeamMemberFromAllProjectCardsCompleted;
            _dataService.GetCardWallInstancesBetweenCompleted += _dataService_GetCardWallInstancesBetweenCompleted;
            _dataService.CopyWallInstanceCompleted += _dataService_CopyWallInstanceCompleted;
            _dataService.RemoveCardSignUpFromWallCompleted += _dataService_RemoveCardSignUpFromWallCompleted;
            _dataService.DeleteTeamMemberCompleted += _dataService_DeleteTeamMemberCompleted;

            ProjectCards = new ObservableCollection<ProjectCardModel>();
            TeamMembers = new ObservableCollection<TeamMemberModel>();
            MingleCards = new ObservableCollection<ProjectCardModel>();

            Settings = new SettingsModel(_dataService);
            _dataService.GetSettingsAsync();
        }

        void _dataService_DeleteTeamMemberCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            var id = (Guid)e.UserState;
            TeamMembers.Remove(TeamMembers.First(t => t.Id == id));
        }

        void _dataService_RemoveCardSignUpFromWallCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            var projectCardNumber = (int) e.UserState;
            var projectCardModel = ProjectCards.First(p => p.CardNumber == projectCardNumber);
            
            if (projectCardModel.AssignedTeamMember1 != null)
            {
                _absentees.AddTeamMember(projectCardModel.AssignedTeamMember1);
                projectCardModel.AssignedTeamMember1 = null;
            }
            
            if (projectCardModel.AssignedTeamMember2 != null)
            {
                _absentees.AddTeamMember(projectCardModel.AssignedTeamMember2);
                projectCardModel.AssignedTeamMember2 = null;
            }

            ProjectCards.Remove(projectCardModel);


            if (_numOfCardsToRemove > 0)
            {
                _numOfCardsToRemove--;
                if(_numOfCardsToRemove == 0)
                    SyncCardsStatusFromMingle();    
            }

        }

        void _dataService_GetSettingsCompleted(object sender, GetSettingsCompletedEventArgs e)
        {
            var settings = e.Result;
            _settings.Point1MappingToNotUrgent = settings.Point1MappingToNotUrgent;
            _settings.Point1MappingToUrgent = settings.Point1MappingToUrgent;
            _settings.ShowDaysSpentForProjectCards = settings.ShowDaysSpentForProjectCards;
            _settings.MingleUsername = settings.MingleUsername;
            _settings.MinglePassword = settings.MinglePassword;
            _settings.MingleStoryUrl = settings.MingleStoryUrl;
            _settings.MingleStoryUrlBringAllCardsFromMingle = settings.MingleStoryUrlBringAllCardsFromMingle;
            _settings.MingleRegressionUrl= settings.MingleRegressionUrl;
            _settings.MingleRegressionUrlBringAllCardsFromMingle= settings.MingleRegressionUrlBringAllCardsFromMingle;
            _settings.MingleDPSUrl = settings.MingleDPSUrl;
            _settings.MingleDPSUrlBringAllCardsFromMingle = settings.MingleDPSUrlBringAllCardsFromMingle;
            _settings.IterationEndDate = DateTime.Parse(settings.IterationEndDate);
            Registry.Settings = _settings;
            OnPropertyChanged("Settings");
            _dataService.GetTeamMembersAsync();
        }

        void _dataService_DetachTeamMemberFromAllProjectCardsCompleted(object sender, DetachTeamMemberFromAllProjectCardsCompletedEventArgs e)
        {
        }


        void dataService_GetTeamMembersCompleted(object sender, GetTeamMembersCompletedEventArgs e)
        {
            var teamMembers = e.Result;
            teamMembers.ToList().ForEach(t =>
                                         {
                                             var teamMemberModel = new TeamMemberModel(t.Id, t.Name, _dataService, t.IceCreams){PhotoUri = t.PhotoUri };
                                             TeamMembers.Add(teamMemberModel);
                                         });

            //assuming this is called only from constructor, we need to now get the project sign ups for today
            CurrentInstanceDate = DateTime.Today;
        }


        void _dataService_AttachTeamMemberToProjectCardCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            SetUpPairingData();
        }


        public void AddProjectCard(int cardNumber = 0)
        {
            if (cardNumber == 0)
            {
                var title = "[Title]";
                _dataService.AddProjectCardAsync(title);
            }
            else
            {
                _dataService.GetProjectCardFromMingleAsync(cardNumber, Settings.MingleUsername, Settings.MinglePassword);
            }

        }
        
        void _dataService_GetProjectCardFromMingleCompleted(object sender, GetProjectCardFromMingleCompletedEventArgs e)
        {
            var projectCard = e.Result;
            if(projectCard == null)
                return;

            AddToProjectCardsCollection(projectCard, Registry.CurrentWall);
            if (IsSyncingAllProjectCards)
            {
                ProjectCards.First(p => p.CardNumber == projectCard.CardNumber).IsSyncing = false;
                SyncCardsStatusFromMingle();
            }
        }

        void dataService_AddProjectCardCompleted(object sender, AddProjectCardCompletedEventArgs e)
        {
            var projectCard = e.Result;
            AddToProjectCardsCollection(projectCard, Registry.CurrentWall);
        }

        private void AddToProjectCardsCollection(ProjectCard projectCard, WallType wall)
        {
            var developmentStage = (StoryStatus)Enum.Parse(typeof(StoryStatus), projectCard.StoryStatus.Replace(" ","").Replace("-",""), true);

            if (ProjectCards.Any(c => c.CardNumber == projectCard.CardNumber))
            {
                var existingCard = ProjectCards.First(c => c.CardNumber == projectCard.CardNumber);
                existingCard.DevStage = developmentStage;
                existingCard.StatusInMingle = projectCard.StoryStatus;
                existingCard.DevEstimate = projectCard.DevEstimate;
                existingCard.Priority = projectCard.Priority;
                return;
            }
            
            var projectCardModel = new ProjectCardModel(_dataService, projectCard, wall);
            ProjectCards.Add(projectCardModel);
        }

        void dataService_GetProjectCardsCompleted(object sender, GetProjectCardsCompletedEventArgs e)
        {
        }

        
        private DateTime _currentInstanceDate;
        public DateTime CurrentInstanceDate 
        {
            get { return _currentInstanceDate; }
            set
            {
                if (_currentInstanceDate == value)
                    return;
                _currentInstanceDate = value;
                Registry.CurrentDate = value;
                _dataService.AddCardWallInstanceOnAsync(value);
                OnPropertyChanged("CurrentInstanceDate");
            }
        }

        private bool _isWallEmpty;
        public bool IsWallEmpty
        {
            get { return _isWallEmpty; }
            set
            {
                if (_isWallEmpty == value)
                    return;
                _isWallEmpty = value;
                OnPropertyChanged("IsWallEmpty");
            }
        }

        void  dataService_AddCardWallInstanceOnCompleted(object sender, AddCardWallInstanceOnCompletedEventArgs e)
        {
            var cardWallInstance = e.Result;
            if(cardWallInstance != null)
                CreateProjectCardsAndTeamMembersForWall(cardWallInstance);
        }

        private void CreateProjectCardsAndTeamMembersForWall(CardWallInstanceOnADate cardWallInstance)
        {
            ProjectCards.Clear();
            Registry.LoadingWallForFirstTime = true;

            if (cardWallInstance.StorySignUps.Count == 0) 
            {
                IsWallEmpty = true;
                Registry.LoadingWallForFirstTime = false;
                return;
            }
            else
                IsWallEmpty = false;


            TeamMembers.ToList().ForEach(t => _absentees.AddTeamMember(t));

            cardWallInstance.StorySignUps.ToList().ForEach(s =>
                                                           {
                                                               var wallType = (WallType)Enum.Parse(typeof(WallType), s.Wall, true);
                                                               var projectCardModel = new ProjectCardModel(_dataService, s.Card, wallType)
                                                                                      {
                                                                                          Position = new Point(s.CardPositionX,s.CardPositionY),
                                                                                          Note = s.Note
                                                                                      };
                                                               ProjectCards.Add(projectCardModel);
                                                               var assignedTeamMember1 = TeamMembers.FirstOrDefault(t => t.Id == (s.Assignees.Count > 0 ? s.Assignees[0].Id : Guid.Empty));
                                                               if (assignedTeamMember1 != null)
                                                               {
                                                                   _absentees.RemoveTeamMember(assignedTeamMember1);
                                                                   projectCardModel.AssignedTeamMember1 = assignedTeamMember1;
                                                               }
                                                               var assignedTeamMember2 = TeamMembers.FirstOrDefault(t => t.Id == (s.Assignees.Count > 1 ? s.Assignees[1].Id : Guid.Empty));
                                                               if (assignedTeamMember2 != null)
                                                               {
                                                                   _absentees.RemoveTeamMember(assignedTeamMember2);
                                                                   projectCardModel.AssignedTeamMember2 = assignedTeamMember2;
                                                               }

                                                               s.Assignees.ToList().ForEach(a =>
                                                                                            {
                                                                                                var teamMember = TeamMembers.First(t => t.Id == a.Id);
                                                                                                teamMember.Wall = wallType;
                                                                                                _absentees.RemoveTeamMember(teamMember);
                                                                                            });

                                                           });

            cardWallInstance.StorySignUps.ToList().ForEach(s =>
                                                           {
                                                               var primaryCard = ProjectCards.First(p => p.CardNumber == s.CardNumber);
                                                               s.SecondaryCards.ToList().ForEach(sec =>
                                                               {
                                                                   var secondaryCard = ProjectCards.FirstOrDefault(p => p.CardNumber == sec);
                                                                   if (secondaryCard != null)
                                                                   {
                                                                       primaryCard.SecondaryProjectCards.Add(secondaryCard);
                                                                       secondaryCard.PrimaryCard = primaryCard;
                                                                   }
                                                               });

                                                           });

            TeamMembers.ToList().ForEach(t => t.RaisePropertyChangeEvent("HasSignUpsOnCurrentWall"));
            StandUpTime = new TimeSpan(0, 0, cardWallInstance.StandupTimeInSeconds);

            Registry.LoadingWallForFirstTime = false;

            SetUpPairingData();

        }



        void _dataService_GetProjectCardsFromMingleCompleted(object sender, GetProjectCardsFromMingleCompletedEventArgs e)
        {
            var projectCards = e.Result;
            var userState = (WallType)e.UserState;

            AddCardToWall(userState, projectCards);
            AddCardToMingleForm(userState, projectCards);

            if (userState == WallType.StoryWall)
            {
                if(Settings.MingleRegressionUrlBringAllCardsFromMingle)
                {
                    _dataService.GetProjectCardsFromMingleAsync(GetMingleApiUrl(Settings.MingleRegressionUrl), Settings.MingleUsername, Settings.MinglePassword, WallType.RegressionWall);
                    return;
                }
                userState = WallType.RegressionWall;
            }
            
            if (userState == WallType.RegressionWall)
            {
                if(Settings.MingleDPSUrlBringAllCardsFromMingle)
                {
                    _dataService.GetProjectCardsFromMingleAsync(GetMingleApiUrl(Settings.MingleDPSUrl), Settings.MingleUsername, Settings.MinglePassword, WallType.DPSWall);
                    return;
                }
            }

            
            ShowApplicableCardsOnWall();
            IsSyncingAllProjectCards = false;
        }

        private void AddCardToMingleForm(WallType userState, ObservableCollection<ProjectCard> projectCards)
        {
            projectCards.ToList().ForEach(c =>
                                          {
                                              if (!MingleCards.Any(p => p.CardNumber == c.CardNumber))
                                                MingleCards.Add(new ProjectCardModel(_dataService, c, userState));
                                          });
        }

        private void AddCardToWall(WallType userState, ObservableCollection<ProjectCard> projectCards)
        {
            if (userState == WallType.StoryWall && Settings.MingleStoryUrlBringAllCardsFromMingle)
            {
                projectCards.ToList().ForEach(c =>
                                              {
                                                  if (!ProjectCards.Any(p => p.CardNumber == c.CardNumber))
                                                      ProjectCards.Add(new ProjectCardModel(_dataService, c, userState));
                                              });
            }
            else if (userState == WallType.RegressionWall && Settings.MingleRegressionUrlBringAllCardsFromMingle)
            {
                projectCards.ToList().ForEach(c =>
                                              {
                                                  if (!ProjectCards.Any(p => p.CardNumber == c.CardNumber))
                                                      ProjectCards.Add(new ProjectCardModel(_dataService, c, userState));
                                              });
            }
            else if (userState == WallType.DPSWall && Settings.MingleDPSUrlBringAllCardsFromMingle)
            {
                projectCards.ToList().ForEach(c =>
                                              {
                                                  if (!ProjectCards.Any(p => p.CardNumber == c.CardNumber))
                                                      ProjectCards.Add(new ProjectCardModel(_dataService, c, userState));
                                              });
            }
        }

        private string GetMingleApiUrl(string mingleUrl)
        {
            if (mingleUrl.IndexOf("/api/v2/projects/") > 0)
                return mingleUrl;

            var queryString = mingleUrl.Substring(mingleUrl.IndexOf("?") + 1);
            if(mingleUrl.StartsWith("https://"))
                mingleUrl = mingleUrl.Replace("https://", "http://");

            mingleUrl = mingleUrl.Replace("/projects/", "/api/v2/projects/");
            mingleUrl = mingleUrl.Remove(mingleUrl.IndexOf("/cards"));
            mingleUrl += "/cards.xml?";
            mingleUrl += queryString;
            return mingleUrl;
        }

        public void AddTeamMemberCard()
        {
            var name = "[Member " + TeamMembers.Count + "]";
            var photoUri = "";
            _dataService.AddTeamMemberAsync(name, photoUri);
            
        }

        void _dataService_AddTeamMemberCompleted(object sender, AddTeamMemberCompletedEventArgs e)
        {
            var teamMember = e.Result;
            TeamMembers.Add(new TeamMemberModel(teamMember.Id, teamMember.Name, _dataService, teamMember.IceCreams) { PhotoUri = teamMember.PhotoUri });
        }

//        public void SetProjectCardInDevelopmentStage(ProjectCardModel card)
//        {
//            _dataService.SetProjectCardInDevelopmentStage(_currentInstanceDate, card.CardNumber, card.DevStage.ToString(),card.Position);
//        }

        public void AttachTeamMemberToProjectCard(TeamMemberModel teamMember, ProjectCardModel projectCard)
        {
            DetachTeamMemberFromAllProjectCardModels(teamMember);
            var success = projectCard.SignUpTeamMemberForThisCard(teamMember);
            if (success)
            {
                _absentees.RemoveTeamMember(teamMember);
                _dataService.AttachTeamMemberToProjectCardAsync(_currentInstanceDate, projectCard.CardNumber, teamMember.Id, teamMember.Position.X, teamMember.Position.Y);
                teamMember.Wall = Registry.CurrentWall;
            }
            else
            {
                _dataService.DetachTeamMemberFromAllProjectCardsAsync(_currentInstanceDate, teamMember.Id, teamMember.Id);
            }
        }

        public void DetachTeamMemberFromAllProjectCards(TeamMemberModel teamMember)
        {
            DetachTeamMemberFromAllProjectCardModels(teamMember);
            _dataService.DetachTeamMemberFromAllProjectCardsAsync(_currentInstanceDate, teamMember.Id, teamMember.Id);
        }

        public void AttachSecondaryProjectCardToProjectCard(ProjectCardModel secondaryCard, ProjectCardModel primaryCard, double projectCardX, double projectCardY)
        {
            DetachProjectCardFromAllProjectCardModels(secondaryCard);
            primaryCard.SignUpSecondaryProjectCard(secondaryCard);
            _dataService.AttachSecondaryProjectCardToProjectCardAsync(_currentInstanceDate, primaryCard.CardNumber, secondaryCard.CardNumber, projectCardX, projectCardY);
        }

        public void DetachProjectCardFromAllProjectCards(ProjectCardModel projectCard)
        {
            DetachProjectCardFromAllProjectCardModels(projectCard);
            _dataService.DetachProjectCardFromAllProjectCardsAsync(_currentInstanceDate, projectCard.CardNumber);
        }

        private void DetachTeamMemberFromAllProjectCardModels(TeamMemberModel teamMember)
        {
            var projectCard = ProjectCards.FirstOrDefault(p => p.AssignedTeamMember1 != null && p.AssignedTeamMember1.Id == teamMember.Id);
            if (projectCard != null)
                projectCard.AssignedTeamMember1 = null;

            projectCard = ProjectCards.FirstOrDefault(p => p.AssignedTeamMember2 != null && p.AssignedTeamMember2.Id == teamMember.Id);
            if (projectCard != null)
                projectCard.AssignedTeamMember2 = null;

            _absentees.AddTeamMember(teamMember);
        }

        private void DetachProjectCardFromAllProjectCardModels(ProjectCardModel projectCard)
        {
            ProjectCards.ToList().ForEach(primaryCard =>
                                        {
                                            var secondaryCard = primaryCard.SecondaryProjectCards.FirstOrDefault(sec => sec.CardNumber == projectCard.CardNumber);
                                            if (secondaryCard != null)
                                            {
                                                secondaryCard.PrimaryCard = null;
                                                primaryCard.SecondaryProjectCards.Remove(secondaryCard);
                                            }
                                        });
        }

        public List<PairModel> GetPairs(ObservableCollection<CardWallInstanceOnADate> cardWallInstances)
        {
            var pairModels = new List<PairModel>();
            CreateEmptyPairModelsForAllTeamMembers(pairModels);

            cardWallInstances.ToList().ForEach(wall => wall.StorySignUps.ToList().ForEach(story =>
                                                                                 {
                                                                                     if (story.Assignees.Count > 0)
                                                                                     {
                                                                                         var pairModel = pairModels.FirstOrDefault(p =>
                                                                                                 story.Assignees.Any(assignee => assignee.Id == p.Members[0].Id) &&
                                                                                                 story.Assignees.Any(assignee => assignee.Id == p.Members[1].Id));

                                                                                         if (pairModel != null)
                                                                                             pairModel.Cards.Add(new ProjectCardModel(_dataService, story.Card, WallType.StoryWall));
                                                                                     }
                                                                                 }));
            return pairModels;
        }

        private void CreateEmptyPairModelsForAllTeamMembers(List<PairModel> pairModels)
        {
            TeamMembers.ToList().ForEach(t1 => 
                                         TeamMembers.ToList().ForEach(t2 =>
                                                                      {
                                                                          if (t1.Name != t2.Name)
                                                                          {
                                                                              if (!pairModels.Any(p =>
                                                                                                  p.Members.Any(m => m.Name == t1.Name) &&
                                                                                                  p.Members.Any(m => m.Name == t2.Name)))
                                                                              {
                                                                                  pairModels.Add(new PairModel(_dataService)
                                                                                                 {
                                                                                                     Members = new ObservableCollection <TeamMemberModel> {t1, t2},
                                                                                                     Cards = new ObservableCollection <ProjectCardModel>()
                                                                                                 });
                                                                              }
                                                                          }
                                                                      }));

            //self pair
            TeamMembers.ToList().ForEach(t => pairModels.Add(new PairModel(_dataService) { Members = new ObservableCollection<TeamMemberModel> { t, t }, Cards = new ObservableCollection<ProjectCardModel>() }));
        }

        private TimeSpan _standUpTime;
        public TimeSpan StandUpTime
        {
            get { return _standUpTime; }
            set
            {
                if (_standUpTime == value)
                    return;
                _standUpTime = value;
                OnPropertyChanged("StandUpTime");
            }
        }

        private DateTime _pairingMatrixStartDate = DateTime.Now.Date.AddDays(-14);
        public DateTime PairingMatrixStartDate
        {
            get { return _pairingMatrixStartDate; }
            set
            {
                if (_pairingMatrixStartDate == value)
                    return;
                _pairingMatrixStartDate = value;
                OnPropertyChanged("PairingMatrixStartDate");
            }
        }

        public void SetUpPairingData()
        {
            _dataService.GetCardWallInstancesBetweenAsync(_pairingMatrixStartDate, _currentInstanceDate);
        }

        void _dataService_GetCardWallInstancesBetweenCompleted(object sender, GetCardWallInstancesBetweenCompletedEventArgs e)
        {
            var pairModels = GetPairs(e.Result);
            TeamMembers.ToList().ForEach(t => 
                {
                    t.SetPairingStats(pairModels);
                    t.SetProcessAssignments(GetProjectCardAssignmentsPerTeamMember(t, e.Result));
                }
                );

        }

        private List<ProjectCardAssignmentModel> GetProjectCardAssignmentsPerTeamMember(TeamMemberModel teamMemberModel, ObservableCollection<CardWallInstanceOnADate> cardWallInstances)
        {
            var projectCardAssignmentModels = new List<ProjectCardAssignmentModel>();
            cardWallInstances.ToList().ForEach(wall => wall.StorySignUps.ToList().ForEach(story =>
            {
                if (story.Assignees.Count > 0 && story.Assignees.Any(a => a.Id == teamMemberModel.Id))
                {
                    var assignmentModel = new ProjectCardAssignmentModel() { Date = wall.Date.ToString(), CardNumbers = story.CardNumber.ToString() + " - " + story.Card.Title };
                    projectCardAssignmentModels.Add(assignmentModel);
                }
            }));
            return projectCardAssignmentModels;
        }


        public void CopyWallFromPreviousDay()
        {
            _dataService.CopyWallInstanceAsync(_currentInstanceDate.AddDays(-1), _currentInstanceDate);
        }

        void _dataService_CopyWallInstanceCompleted(object sender, CopyWallInstanceCompletedEventArgs e)
        {
            var wallInstance = e.Result;
            if(wallInstance == null)
                return;

            CreateProjectCardsAndTeamMembersForWall(wallInstance);
        }

        private void ShowApplicableCardsOnWall()
        {
            ProjectCards.ToList().ForEach(c => c.RaisePropertyChangeEvent("IsCardVisibleInCurrentWall"));
            MingleCards.ToList().ForEach(c => c.RaisePropertyChangeEvent("IsCardVisibleInCurrentWall"));
            TeamMembers.ToList().ForEach(c => c.RaisePropertyChangeEvent("HasSignUpsOnCurrentWall"));
        }

        public void GetStoryWallCards()
        {
            var currentWall = WallType.StoryWall;
            Registry.CurrentWall = currentWall;
            ShowApplicableCardsOnWall();
        }

        public void GetRegressionWallCards()
        {
            var currentWall = WallType.RegressionWall;
            Registry.CurrentWall = currentWall;
            ShowApplicableCardsOnWall();
        }

        public void GetDPSWallCards()
        {
            var currentWall = WallType.DPSWall;
            Registry.CurrentWall = currentWall;
            ShowApplicableCardsOnWall();
        }

        public void GetMingleCards()
        {
            if (Settings.MingleStoryUrlBringAllCardsFromMingle)
                _dataService.GetProjectCardsFromMingleAsync(GetMingleApiUrl(Settings.MingleStoryUrl), Settings.MingleUsername, Settings.MinglePassword, WallType.StoryWall);

            else if(Settings.MingleRegressionUrlBringAllCardsFromMingle)
                _dataService.GetProjectCardsFromMingleAsync(GetMingleApiUrl(Settings.MingleStoryUrl), Settings.MingleUsername, Settings.MinglePassword, WallType.RegressionWall);

            else if(Settings.MingleDPSUrlBringAllCardsFromMingle)
                _dataService.GetProjectCardsFromMingleAsync(GetMingleApiUrl(Settings.MingleStoryUrl), Settings.MingleUsername, Settings.MinglePassword, WallType.DPSWall);
            else
                IsSyncingAllProjectCards = false;

        }

        private AbsenteesModel _absentees = new AbsenteesModel();
        public AbsenteesModel Absentees
        {
            get { return _absentees; }
        }


        private bool _isSyncingAllProjectCards;
        public bool IsSyncingAllProjectCards
        {
            get { return _isSyncingAllProjectCards; }
            set
            {
                if (_isSyncingAllProjectCards == value)
                    return;
                _isSyncingAllProjectCards = value;
                OnPropertyChanged("IsSyncingAllProjectCards");
            }
        }

         
        private int _currentProjectCardToSync = -1;
        public void SyncCardsFromMingle()
        {
            DeleteCardsWithoutAnySignUps();
        }

        private int _numOfCardsToRemove = 0;
        private void DeleteCardsWithoutAnySignUps()
        {
            var cardsWithoutSignUps = ProjectCards.Where(p => p.AssignedTeamMember1 == null && p.AssignedTeamMember2 == null);
            var cardsToRemove = cardsWithoutSignUps.ToList();
            _numOfCardsToRemove = cardsToRemove.Count;
            if (_numOfCardsToRemove == 0)
                SyncCardsStatusFromMingle();
            else
                cardsToRemove.ForEach(p => RemoveProjectCardFromWall(CurrentInstanceDate, p.CardNumber));
        }

        private void BringNewCardsFromMingle()
        {
            GetMingleCards();
        }

        private void SyncCardsStatusFromMingle()
        {
            IsSyncingAllProjectCards = true;
            _currentProjectCardToSync++;
            if (_currentProjectCardToSync < ProjectCards.Count)
            {
                while (!ProjectCards[_currentProjectCardToSync].IsMingleCard)
                {
                    _currentProjectCardToSync++;
                    if (_currentProjectCardToSync == ProjectCards.Count)
                    {
                        _currentProjectCardToSync = -1;
                        BringNewCardsFromMingle();
                        return;
                    }
                }
                var projectCardModel = ProjectCards[_currentProjectCardToSync];
                projectCardModel.IsSyncing = true;
                _dataService.GetProjectCardFromMingleAsync(projectCardModel.CardNumber, Settings.MingleUsername, Settings.MinglePassword);
            }
            else
            {
                _currentProjectCardToSync = -1;
                BringNewCardsFromMingle();
            }
        }

        private SettingsModel _settings;
        public SettingsModel Settings
        {
            get { return _settings; }
            set
            {
                if (_settings == value)
                    return;
                _settings = value;
                OnPropertyChanged("Settings");
            }
        }

        public void RemoveProjectCardFromWall(DateTime date, int cardNumber)
        {
            _dataService.RemoveCardSignUpFromWallAsync(date,cardNumber, cardNumber);
        }

        public void DeleteTeamMemberCard(Guid id)
        {
            _dataService.DeleteTeamMemberAsync(id,id);
        }

        public void SetStandupTime(TimeSpan time)
        {
            _dataService.SetStandupTimeAsync(_currentInstanceDate, time);
        }

        public void SaveData()
        {
            _dataService.SaveDataAsync();
        }

    }
}